using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using PickGold.Charting;

namespace PickGold.Charting.ChartTypes
{
	internal class RangeChart : SplineChart
	{
		private float _fourthPointY2Value = float.NaN;
		private Series _series;
		private float _thirdPointY2Value = float.NaN;
		internal GraphicsPath areaBottomPath = new GraphicsPath();
		protected GraphicsPath areaPath;
		internal bool gradientFill;
		internal bool indexedBasedX;
		internal PointF[] lowPoints;

		public RangeChart()
		{
			base.drawOutsideLines = true;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (this.areaBottomPath != null)
				{
					this.areaBottomPath.Dispose();
					this.areaBottomPath = null;
				}
				if (this.areaPath != null)
				{
					this.areaPath.Dispose();
					this.areaPath = null;
				}
			}
			base.Dispose(disposing);
		}

		internal GraphicsPath Draw3DSplinePolygon(ChartGraphics graph, ChartArea area, float positionZ, Color backColor, Color borderColor, int borderWidth, DataPoint3D firstPoint, DataPoint3D secondPoint, DataPoint3D thirdPoint, DataPoint3D fourthPoint, ArrayList points, float tension, DrawingOperationTypes operationType, LineSegmentType lineSegmentType, bool forceThinBorder)
		{
			if (tension == 0f)
			{
				SurfaceNames thinBorders = 0;
				if (forceThinBorder)
				{
					thinBorders = SurfaceNames.Right | SurfaceNames.Left;
				}
				return graph.Draw3DPolygon(area, area.matrix3D, SurfaceNames.Front, positionZ, backColor, borderColor, borderWidth, firstPoint, secondPoint, thirdPoint, fourthPoint, operationType, lineSegmentType, thinBorders);
			}
			bool flag = (operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement;
			GraphicsPath path = new GraphicsPath();
			GraphicsPath addingPath = graph.GetSplineFlattenPath(area, positionZ, firstPoint, secondPoint, points, tension, false, true, 0);
			GraphicsPath path3 = graph.GetSplineFlattenPath(area, positionZ, thirdPoint, fourthPoint, points, tension, false, true, 1);
			path.AddPath(addingPath, true);
			path.AddPath(path3, true);
			path.CloseAllFigures();
			Point3D[] pointdArray = new Point3D[] { new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ), new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ), new Point3D((float)thirdPoint.xPosition, (float)thirdPoint.yPosition, positionZ) };
			area.matrix3D.TransformPoints(pointdArray);
			bool visiblePolygon = ChartGraphics.IsSurfaceVisible(pointdArray[0], pointdArray[1], pointdArray[2]);
			Color color = area.matrix3D.GetPolygonLight(pointdArray, backColor, visiblePolygon, (float)area.Area3DStyle.Rotation, SurfaceNames.Front, area.ReverseSeriesOrder);
			Color color2 = borderColor;
			if (color2 == Color.Empty)
			{
				color2 = ChartGraphics.GetGradientColor(backColor, Color.Black, 0.2);
			}
			Pen pen = null;
			if (flag)
			{
				SmoothingMode smoothingMode = graph.SmoothingMode;
				graph.SmoothingMode = SmoothingMode.Default;
				using (Brush brush = new SolidBrush(color))
				{
					graph.FillPath(brush, path);
				}
				graph.SmoothingMode = smoothingMode;
				if (forceThinBorder)
				{
					graph.DrawPath(new Pen(color2, 1f), path);
				}
				else if (color.A == 0xff)
				{
					graph.DrawPath(new Pen(color, 1f), path);
				}
				pen = new Pen(color2, (float)borderWidth);
				pen.StartCap = LineCap.Round;
				pen.EndCap = LineCap.Round;
				graph.DrawPath(pen, addingPath);
				graph.DrawPath(pen, path3);
				if (lineSegmentType == LineSegmentType.First)
				{
					graph.DrawLine(pen, addingPath.PathPoints[0], path3.GetLastPoint());
				}
				else if (lineSegmentType == LineSegmentType.Last)
				{
					graph.DrawLine(pen, addingPath.GetLastPoint(), path3.PathPoints[0]);
				}
			}
			if ((path != null) && (pen != null))
			{
				try
				{
					path.Widen(pen);
				}
				catch (OutOfMemoryException)
				{
				}
				catch (ArgumentException)
				{
				}
			}
			return path;
		}

		protected override GraphicsPath Draw3DSurface(ChartArea area, ChartGraphics graph, Matrix3D matrix, LightStyle lightStyle, DataPoint3D prevDataPointEx, float positionZ, float depth, ArrayList points, int pointIndex, int pointLoopIndex, float tension, DrawingOperationTypes operationType, float topDarkening, float bottomDarkening, PointF thirdPointPosition, PointF fourthPointPosition, bool clippedSegment)
		{
			GraphicsPath path = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) ? new GraphicsPath() : null;
			if (base.centerPointIndex == 0x7fffffff)
			{
				base.centerPointIndex = base.GetCenterPointIndex(points);
			}
			DataPoint3D secondPoint = (DataPoint3D)points[pointIndex];
			int neighborPointIndex = pointIndex;
			DataPoint3D firstPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
			bool reversed = false;
			if (firstPoint.index > secondPoint.index)
			{
				DataPoint3D pointd3 = firstPoint;
				firstPoint = secondPoint;
				secondPoint = pointd3;
				reversed = true;
			}
			if ((matrix.Perspective != 0f) && (base.centerPointIndex != 0x7fffffff))
			{
				neighborPointIndex = pointIndex;
				if (pointIndex != (base.centerPointIndex + 1))
				{
					firstPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
				}
				else if (!area.ReverseSeriesOrder)
				{
					secondPoint = ChartGraphics.FindPointByIndex(points, firstPoint.index + 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
				}
				else
				{
					firstPoint = secondPoint;
					secondPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
				}
			}
			if ((firstPoint != null) && (secondPoint != null))
			{
				return this.Draw3DSurface(firstPoint, secondPoint, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, LineSegmentType.Single, topDarkening, bottomDarkening, thirdPointPosition, fourthPointPosition, clippedSegment, true, true);
			}
			return path;
		}

		protected override GraphicsPath Draw3DSurface(DataPoint3D firstPoint, DataPoint3D secondPoint, bool reversed, ChartArea area, ChartGraphics graph, Matrix3D matrix, LightStyle lightStyle, DataPoint3D prevDataPointEx, float positionZ, float depth, ArrayList points, int pointIndex, int pointLoopIndex, float tension, DrawingOperationTypes operationType, LineSegmentType surfaceSegmentType, float topDarkening, float bottomDarkening, PointF thirdPointPosition, PointF fourthPointPosition, bool clippedSegment, bool clipOnTop, bool clipOnBottom)
		{
			PointF tf;
			PointF tf2;
			GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) ? new GraphicsPath() : null;
			DataPoint3D pointd = secondPoint;
			if (prevDataPointEx.dataPoint.IsEmpty)
			{
				pointd = prevDataPointEx;
			}
			else if (firstPoint.index > secondPoint.index)
			{
				pointd = firstPoint;
			}
			Color gray = base.useBorderColor ? pointd.dataPoint.BorderColor : pointd.dataPoint.Color;
			ChartDashStyle borderDashStyle = pointd.dataPoint.BorderDashStyle;
			if (pointd.dataPoint.IsEmpty && (pointd.dataPoint.Color == Color.Empty))
			{
				gray = Color.Gray;
			}
			if (pointd.dataPoint.IsEmpty && (pointd.dataPoint.BorderDashStyle == ChartDashStyle.NotSet))
			{
				borderDashStyle = ChartDashStyle.Solid;
			}
			float position = (float)base.VAxis.GetPosition(base.VAxis.Crossing);
			this.GetBottomPointsPosition(base.Common, area, position, ref firstPoint, ref secondPoint, out tf, out tf2);
			if (!float.IsNaN(thirdPointPosition.Y))
			{
				tf.Y = thirdPointPosition.Y;
			}
			if (!float.IsNaN(fourthPointPosition.Y))
			{
				tf2.Y = fourthPointPosition.Y;
			}
			double num2 = 0.0001;
			if (((Math.Abs((double)(firstPoint.yPosition - tf.Y)) > num2) && (Math.Abs((double)(secondPoint.yPosition - tf2.Y)) > num2)) && (((firstPoint.yPosition > tf.Y) && (secondPoint.yPosition < tf2.Y)) || ((firstPoint.yPosition < tf.Y) && (secondPoint.yPosition > tf2.Y))))
			{
				if (tension != 0f)
				{
					throw new InvalidOperationException(SR.Exception3DSplineY1ValueIsLessThenY2);
				}
				PointF tf3 = ChartGraphics.GetLinesIntersection((float)firstPoint.xPosition, (float)firstPoint.yPosition, (float)secondPoint.xPosition, (float)secondPoint.yPosition, tf.X, tf.Y, tf2.X, tf2.Y);
				DataPoint3D pointd2 = new DataPoint3D();
				pointd2.xPosition = tf3.X;
				pointd2.yPosition = tf3.Y;
				bool flag = true;
				if (double.IsNaN((double)tf3.X) || double.IsNaN((double)tf3.Y))
				{
					flag = false;
				}
				else
				{
					if ((((decimal)tf3.X) == ((decimal)firstPoint.xPosition)) && (((decimal)tf3.Y) == ((decimal)firstPoint.yPosition)))
					{
						flag = false;
					}
					if ((((decimal)tf3.X) == ((decimal)secondPoint.xPosition)) && (((decimal)tf3.Y) == ((decimal)secondPoint.yPosition)))
					{
						flag = false;
					}
				}
				if (flag)
				{
					reversed = false;
					if ((pointIndex + 1) < points.Count)
					{
						DataPoint3D pointd3 = (DataPoint3D)points[pointIndex + 1];
						if (pointd3.index == firstPoint.index)
						{
							reversed = true;
						}
					}
					for (int i = 0; i <= 1; i++)
					{
						GraphicsPath addingPath = null;
						if (((i == 0) && !reversed) || ((i == 1) && reversed))
						{
							this._fourthPointY2Value = (float)pointd2.yPosition;
							pointd2.dataPoint = secondPoint.dataPoint;
							pointd2.index = secondPoint.index;
							addingPath = this.Draw3DSurface(firstPoint, pointd2, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening, new PointF(float.NaN, float.NaN), new PointF(float.NaN, float.NaN), clippedSegment, true, true);
						}
						if (((i == 1) && !reversed) || ((i == 0) && reversed))
						{
							this._thirdPointY2Value = (float)pointd2.yPosition;
							pointd2.dataPoint = firstPoint.dataPoint;
							pointd2.index = firstPoint.index;
							addingPath = this.Draw3DSurface(pointd2, secondPoint, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening, new PointF(float.NaN, float.NaN), new PointF(float.NaN, float.NaN), clippedSegment, true, true);
						}
						if (((resultPath != null) && (addingPath != null)) && (addingPath.PointCount > 0))
						{
							resultPath.AddPath(addingPath, true);
						}
						this._thirdPointY2Value = float.NaN;
						this._fourthPointY2Value = float.NaN;
					}
					return resultPath;
				}
			}
			float x = (float)Math.Min(firstPoint.xPosition, secondPoint.xPosition);
			float num5 = (float)Math.Min(firstPoint.yPosition, secondPoint.yPosition);
			num5 = Math.Min(num5, position);
			float num6 = (float)Math.Max(firstPoint.xPosition, secondPoint.xPosition);
			float num7 = (float)Math.Max(firstPoint.yPosition, secondPoint.yPosition);
			num7 = Math.Max(num7, position);
			RectangleF ef = new RectangleF(x, num5, num6 - x, num7 - num5);
			SurfaceNames visibleSurfaces = graph.GetVisibleSurfaces(ef, positionZ, depth, matrix);
			bool upSideDown = false;
			if ((firstPoint.yPosition >= tf.Y) && (secondPoint.yPosition >= tf2.Y))
			{
				upSideDown = true;
				bool flag3 = (visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top;
				bool flag4 = (visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom;
				visibleSurfaces ^= SurfaceNames.Bottom;
				visibleSurfaces ^= SurfaceNames.Top;
				if (flag3)
				{
					visibleSurfaces |= SurfaceNames.Bottom;
				}
				if (flag4)
				{
					visibleSurfaces |= SurfaceNames.Top;
				}
			}
			this.GetTopSurfaceVisibility(area, firstPoint, secondPoint, upSideDown, positionZ, depth, matrix, ref visibleSurfaces);
			bool flag5 = true;
			if (tension != 0f)
			{
				if ((visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom)
				{
					flag5 = false;
				}
				if (((visibleSurfaces & SurfaceNames.Bottom) == 0) && ((visibleSurfaces & SurfaceNames.Top) == 0))
				{
					flag5 = false;
				}
				visibleSurfaces |= SurfaceNames.Bottom;
				visibleSurfaces |= SurfaceNames.Top;
			}
			firstPoint.xPosition = Math.Round(firstPoint.xPosition, 5);
			firstPoint.yPosition = Math.Round(firstPoint.yPosition, 5);
			secondPoint.xPosition = Math.Round(secondPoint.xPosition, 5);
			secondPoint.yPosition = Math.Round(secondPoint.yPosition, 5);
			if (!base.ClipTopPoints(resultPath, ref firstPoint, ref secondPoint, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening))
			{
				if (base.ClipBottomPoints(resultPath, ref firstPoint, ref secondPoint, ref tf, ref tf2, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening))
				{
					return resultPath;
				}
				for (int j = 1; j <= 2; j++)
				{
					SurfaceNames[] namesArray = null;
					if (flag5)
					{
						namesArray = new SurfaceNames[] { SurfaceNames.Back, SurfaceNames.Bottom, SurfaceNames.Top, SurfaceNames.Left, SurfaceNames.Right, SurfaceNames.Front };
					}
					else
					{
						namesArray = new SurfaceNames[] { SurfaceNames.Back, SurfaceNames.Top, SurfaceNames.Bottom, SurfaceNames.Left, SurfaceNames.Right, SurfaceNames.Front };
					}
					LineSegmentType middle = LineSegmentType.Middle;
					foreach (SurfaceNames names2 in namesArray)
					{
						DataPoint3D pointd14;
						DataPoint3D pointd15;
						if (ChartGraphics.ShouldDrawLineChartSurface(area, area.ReverseSeriesOrder, names2, visibleSurfaces, gray, points, firstPoint, secondPoint, base.multiSeries, ref middle) != j)
						{
							goto Label_0C28;
						}
						Color backColor = gray;
						Color borderColor = pointd.dataPoint.BorderColor;
						if (j == 1)
						{
							if (backColor.A == 0xff)
							{
								goto Label_0C28;
							}
							backColor = Color.Transparent;
							if (borderColor == Color.Empty)
							{
								borderColor = ChartGraphics.GetGradientColor(gray, Color.Black, 0.2);
							}
						}
						GraphicsPath path3 = null;
						switch (names2)
						{
							case SurfaceNames.Front:
								pointd14 = new DataPoint3D();
								pointd14.dataPoint = firstPoint.dataPoint;
								pointd14.index = firstPoint.index;
								pointd14.xPosition = firstPoint.xPosition;
								pointd14.yPosition = tf.Y;
								pointd15 = new DataPoint3D();
								pointd15.dataPoint = secondPoint.dataPoint;
								pointd15.index = secondPoint.index;
								pointd15.xPosition = secondPoint.xPosition;
								pointd15.yPosition = tf2.Y;
								if (area.ReverseSeriesOrder)
								{
									if (middle != LineSegmentType.First)
									{
										goto Label_0B8C;
									}
									middle = LineSegmentType.Last;
								}
								goto Label_0B94;

							case SurfaceNames.Back:
								{
									DataPoint3D fourthPoint = new DataPoint3D();
									fourthPoint.dataPoint = firstPoint.dataPoint;
									fourthPoint.index = firstPoint.index;
									fourthPoint.xPosition = firstPoint.xPosition;
									fourthPoint.yPosition = tf.Y;
									DataPoint3D thirdPoint = new DataPoint3D();
									thirdPoint.dataPoint = secondPoint.dataPoint;
									thirdPoint.index = secondPoint.index;
									thirdPoint.xPosition = secondPoint.xPosition;
									thirdPoint.yPosition = tf2.Y;
									path3 = this.Draw3DSplinePolygon(graph, area, positionZ, backColor, borderColor, pointd.dataPoint.BorderWidth, firstPoint, secondPoint, thirdPoint, fourthPoint, points, tension, operationType, middle, base.showPointLines);
									goto Label_0C03;
								}
							case (SurfaceNames.Back | SurfaceNames.Front):
								goto Label_0C03;

							case SurfaceNames.Left:
								if (((surfaceSegmentType == LineSegmentType.Single) || (!area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.First))) || (area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.Last)))
								{
									DataPoint3D pointd6 = (firstPoint.xPosition <= secondPoint.xPosition) ? firstPoint : secondPoint;
									DataPoint3D pointd7 = new DataPoint3D();
									pointd7.xPosition = pointd6.xPosition;
									pointd7.yPosition = (firstPoint.xPosition <= secondPoint.xPosition) ? ((double)tf.Y) : ((double)tf2.Y);
									DataPoint3D pointd8 = new DataPoint3D();
									pointd8.xPosition = pointd6.xPosition;
									pointd8.yPosition = pointd6.yPosition;
									path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, backColor, borderColor, pointd.dataPoint.BorderWidth, borderDashStyle, pointd7, pointd8, points, pointIndex, 0f, operationType, LineSegmentType.Single, false, true, area.ReverseSeriesOrder, base.multiSeries, 0, true);
								}
								goto Label_0C03;

							case SurfaceNames.Right:
								if (((surfaceSegmentType == LineSegmentType.Single) || (!area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.Last))) || (area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.First)))
								{
									DataPoint3D pointd9 = (secondPoint.xPosition >= firstPoint.xPosition) ? secondPoint : firstPoint;
									DataPoint3D pointd10 = new DataPoint3D();
									pointd10.xPosition = pointd9.xPosition;
									pointd10.yPosition = (secondPoint.xPosition >= firstPoint.xPosition) ? ((double)tf2.Y) : ((double)tf.Y);
									DataPoint3D pointd11 = new DataPoint3D();
									pointd11.xPosition = pointd9.xPosition;
									pointd11.yPosition = pointd9.yPosition;
									path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, backColor, borderColor, pointd.dataPoint.BorderWidth, borderDashStyle, pointd10, pointd11, points, pointIndex, 0f, operationType, LineSegmentType.Single, false, true, area.ReverseSeriesOrder, base.multiSeries, 0, true);
								}
								goto Label_0C03;

							case SurfaceNames.Top:
								path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, backColor, borderColor, pointd.dataPoint.BorderWidth, borderDashStyle, firstPoint, secondPoint, points, pointIndex, tension, operationType, LineSegmentType.Middle, base.showPointLines, false, area.ReverseSeriesOrder, base.multiSeries, 0, true);
								break;

							case SurfaceNames.Bottom:
								{
									DataPoint3D pointd4 = new DataPoint3D();
									pointd4.dataPoint = firstPoint.dataPoint;
									pointd4.index = firstPoint.index;
									pointd4.xPosition = firstPoint.xPosition;
									pointd4.yPosition = tf.Y;
									DataPoint3D pointd5 = new DataPoint3D();
									pointd5.dataPoint = secondPoint.dataPoint;
									pointd5.index = secondPoint.index;
									pointd5.xPosition = secondPoint.xPosition;
									pointd5.yPosition = tf2.Y;
									path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, backColor, borderColor, pointd.dataPoint.BorderWidth, borderDashStyle, pointd4, pointd5, points, pointIndex, tension, operationType, LineSegmentType.Middle, base.showPointLines, false, area.ReverseSeriesOrder, base.multiSeries, 1, true);
									goto Label_0C03;
								}
						}
						goto Label_0C03;
					Label_0B8C:
						if (middle == LineSegmentType.Last)
						{
							middle = LineSegmentType.First;
						}
					Label_0B94:
						if (surfaceSegmentType != LineSegmentType.Single)
						{
							if (((surfaceSegmentType == LineSegmentType.Middle) || ((surfaceSegmentType == LineSegmentType.First) && (middle != LineSegmentType.First))) || ((surfaceSegmentType == LineSegmentType.Last) && (middle != LineSegmentType.Last)))
							{
								middle = LineSegmentType.Middle;
							}
							if (reversed)
							{
								switch (middle)
								{
									case LineSegmentType.First:
										middle = LineSegmentType.Last;
										break;

									case LineSegmentType.Last:
										middle = LineSegmentType.First;
										break;
								}
							}
						}
						path3 = this.Draw3DSplinePolygon(graph, area, positionZ + depth, backColor, borderColor, pointd.dataPoint.BorderWidth, firstPoint, secondPoint, pointd15, pointd14, points, tension, operationType, middle, base.showPointLines);
					Label_0C03:
						if (((j == 2) && (resultPath != null)) && ((path3 != null) && (path3.PointCount > 0)))
						{
							resultPath.CloseFigure();
							resultPath.AddPath(path3, true);
						}
					Label_0C28: ;
					}
				}
			}
			return resultPath;
		}

		protected override void DrawLine(ChartGraphics graph, CommonElements common, DataPoint point, Series series, PointF[] points, int pointIndex, float tension)
		{
			if (point.YValues.Length < 2)
			{
				throw new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, "2"));
			}
			if (pointIndex <= 0)
			{
				return;
			}
			if (base.YValueIndex == 1)
			{
				return;
			}
			if (this._series != null)
			{
				if (this._series.Name != series.Name)
				{
					this.FillLastSeriesGradient(graph);
					this._series = series;
					this.lowPoints = null;
					this.areaBottomPath.Reset();
				}
			}
			else
			{
				this._series = series;
			}
			if (this.lowPoints == null)
			{
				base.YValueIndex = 1;
				this.lowPoints = this.GetPointsPosition(graph, series, this.indexedBasedX);
				base.YValueIndex = 0;
			}
			PointF tf = points[pointIndex - 1];
			PointF tf2 = points[pointIndex];
			PointF tf3 = this.lowPoints[pointIndex - 1];
			PointF tf4 = this.lowPoints[pointIndex];
			Brush brush = null;
			if (point.BackHatchStyle != ChartHatchStyle.None)
			{
				brush = graph.GetHatchBrush(point.BackHatchStyle, point.Color, point.BackSecondaryColor);
			}
			else if (point.BackGradientStyle != GradientStyle.None)
			{
				this.gradientFill = true;
				this._series = point.series;
			}
			else if (((point.BackImage.Length > 0) && (point.BackImageWrapMode != ChartImageWrapMode.Unscaled)) && (point.BackImageWrapMode != ChartImageWrapMode.Scaled))
			{
				brush = graph.GetTextureBrush(point.BackImage, point.BackImageTransparentColor, point.BackImageWrapMode, point.Color);
			}
			else
			{
				brush = new SolidBrush(point.Color);
			}
			GraphicsPath path = new GraphicsPath();
			path.AddLine(tf.X, tf3.Y, tf.X, tf.Y);
			if (base.lineTension == 0f)
			{
				path.AddLine(points[pointIndex - 1], points[pointIndex]);
			}
			else
			{
				path.AddCurve(points, pointIndex - 1, 1, base.lineTension);
			}
			path.AddLine(tf2.X, tf2.Y, tf2.X, tf4.Y);
			if (graph.ActiveRenderingType == RenderingType.Svg)
			{
				using (GraphicsPath path2 = new GraphicsPath())
				{
					if (base.lineTension == 0f)
					{
						path.AddLine(this.lowPoints[pointIndex - 1], this.lowPoints[pointIndex]);
					}
					else
					{
						path2.AddCurve(this.lowPoints, pointIndex - 1, 1, base.lineTension);
						path2.Flatten();
						PointF[] pathPoints = path2.PathPoints;
						PointF[] tfArray2 = new PointF[pathPoints.Length];
						int index = pathPoints.Length - 1;
						foreach (PointF tf5 in pathPoints)
						{
							tfArray2[index] = tf5;
							index--;
						}
						if (tfArray2.Length == 2)
						{
							tfArray2 = new PointF[] { tfArray2[0], tfArray2[1], tfArray2[1] };
						}
						path.AddPolygon(tfArray2);
					}
					goto Label_03AF;
				}
			}
			if (base.lineTension == 0f)
			{
				path.AddLine(this.lowPoints[pointIndex - 1], this.lowPoints[pointIndex]);
			}
			else
			{
				path.AddCurve(this.lowPoints, pointIndex - 1, 1, base.lineTension);
			}
		Label_03AF:
			if (!base.clipRegionSet)
			{
				double num2 = base.indexedSeries ? ((double)(pointIndex + 1)) : series.Points[pointIndex].XValue;
				double num3 = base.indexedSeries ? ((double)pointIndex) : series.Points[pointIndex - 1].XValue;
				if ((((num3 < base.hAxisMin) || (num3 > base.hAxisMax)) || ((num2 > base.hAxisMax) || (num2 < base.hAxisMin))) || (((series.Points[pointIndex - 1].YValues[1] < base.vAxisMin) || (series.Points[pointIndex - 1].YValues[1] > base.vAxisMax)) || ((series.Points[pointIndex].YValues[1] < base.vAxisMin) || (series.Points[pointIndex].YValues[1] > base.vAxisMax))))
				{
					graph.SetClip(base.Area.PlotAreaPosition.ToRectangleF());
					base.clipRegionSet = true;
				}
			}
			if (((series.ShadowColor != Color.Empty) && (series.ShadowOffset != 0)) && ((point.Color != Color.Empty) && (point.Color != Color.Transparent)))
			{
				Matrix matrix = graph.Transform.Clone();
				matrix.Translate((float)series.ShadowOffset, (float)series.ShadowOffset);
				Matrix transform = graph.Transform;
				graph.Transform = matrix;
				Region region = new Region(path);
				using (Brush brush2 = new SolidBrush((series.ShadowColor.A != 0xff) ? series.ShadowColor : Color.FromArgb(point.Color.A / 2, series.ShadowColor)))
				{
					Region clip = null;
					if (!graph.IsClipEmpty && !graph.Clip.IsInfinite(graph.Graphics))
					{
						clip = graph.Clip;
						clip.Translate((int)(series.ShadowOffset + 1), (int)(series.ShadowOffset + 1));
						graph.Clip = clip;
					}
					graph.FillRegion(brush2, region);
					using (Pen pen = new Pen(brush2, 1f))
					{
						if (pointIndex == 0)
						{
							graph.DrawLine(pen, tf.X, tf3.Y, tf.X, tf.Y);
						}
						if (pointIndex == (series.Points.Count - 1))
						{
							graph.DrawLine(pen, tf2.X, tf2.Y, tf2.X, tf4.Y);
						}
					}
					graph.Transform = transform;
					base.drawShadowOnly = true;
					base.DrawLine(graph, common, point, series, points, pointIndex, tension);
					base.YValueIndex = 1;
					base.DrawLine(graph, common, point, series, this.lowPoints, pointIndex, tension);
					base.YValueIndex = 0;
					base.drawShadowOnly = false;
					if (clip != null)
					{
						clip = graph.Clip;
						clip.Translate(-(series.ShadowOffset + 1), -(series.ShadowOffset + 1));
						graph.Clip = clip;
					}
				}
			}
			if (!this.gradientFill)
			{
				SmoothingMode smoothingMode = graph.SmoothingMode;
				graph.SmoothingMode = SmoothingMode.None;
				path.CloseAllFigures();
				graph.FillPath(brush, path);
				graph.SmoothingMode = smoothingMode;
				if (graph.SmoothingMode != SmoothingMode.None)
				{
					Pen pen2 = new Pen(brush, 1f);
					HatchBrush brush3 = brush as HatchBrush;
					if (brush3 != null)
					{
						pen2.Color = brush3.ForegroundColor;
					}
					if (pointIndex == 0)
					{
						graph.DrawLine(pen2, tf.X, tf3.Y, tf.X, tf.Y);
					}
					if (pointIndex == (series.Points.Count - 1))
					{
						graph.DrawLine(pen2, tf2.X, tf2.Y, tf2.X, tf4.Y);
					}
					if (base.lineTension == 0f)
					{
						graph.DrawLine(pen2, points[pointIndex - 1], points[pointIndex]);
					}
					else
					{
						graph.DrawCurve(pen2, points, pointIndex - 1, 1, base.lineTension);
					}
					if (base.lineTension == 0f)
					{
						graph.DrawLine(pen2, this.lowPoints[pointIndex - 1], this.lowPoints[pointIndex]);
					}
					else
					{
						graph.DrawCurve(pen2, this.lowPoints, pointIndex - 1, 1, base.lineTension);
					}
				}
			}
			if (this.areaPath == null)
			{
				this.areaPath = new GraphicsPath();
				this.areaPath.AddLine(tf.X, tf3.Y, tf.X, tf.Y);
			}
			if (base.lineTension == 0f)
			{
				this.areaPath.AddLine(points[pointIndex - 1], points[pointIndex]);
			}
			else
			{
				this.areaPath.AddCurve(points, pointIndex - 1, 1, base.lineTension);
			}
			if (base.lineTension == 0f)
			{
				this.areaBottomPath.AddLine(this.lowPoints[pointIndex - 1], this.lowPoints[pointIndex]);
			}
			else
			{
				this.areaBottomPath.AddCurve(this.lowPoints, pointIndex - 1, 1, base.lineTension);
			}
			if ((((point.BorderWidth > 0) && (point.BorderDashStyle != ChartDashStyle.NotSet)) && (point.BorderColor != Color.Empty)) || (brush is SolidBrush))
			{
				base.useBorderColor = true;
				base.disableShadow = true;
				base.DrawLine(graph, common, point, series, points, pointIndex, tension);
				base.YValueIndex = 1;
				base.DrawLine(graph, common, point, series, this.lowPoints, pointIndex, tension);
				base.YValueIndex = 0;
				base.useBorderColor = false;
				base.disableShadow = false;
			}
			if (common.ProcessModeRegions)
			{
				path.AddLine(tf.X, tf3.Y, tf.X, tf.Y);
				if (base.lineTension == 0f)
				{
					path.AddLine(points[pointIndex - 1], points[pointIndex]);
				}
				else
				{
					path.AddCurve(points, pointIndex - 1, 1, base.lineTension);
				}
				path.AddLine(tf2.X, tf2.Y, tf2.X, tf4.Y);
				if (base.lineTension == 0f)
				{
					path.AddLine(this.lowPoints[pointIndex - 1], this.lowPoints[pointIndex]);
				}
				else
				{
					path.AddCurve(this.lowPoints, pointIndex - 1, 1, base.lineTension);
				}
				GraphicsPath path3 = new GraphicsPath();
				path3.AddLine(tf.X, tf3.Y, tf.X, tf.Y);
				if (base.lineTension == 0f)
				{
					path3.AddLine(points[pointIndex - 1], points[pointIndex]);
				}
				else
				{
					path3.AddCurve(points, pointIndex - 1, 1, base.lineTension);
					path3.Flatten();
				}
				path3.AddLine(tf2.X, tf2.Y, tf2.X, tf4.Y);
				if (base.lineTension == 0f)
				{
					path3.AddLine(this.lowPoints[pointIndex - 1], this.lowPoints[pointIndex]);
				}
				else
				{
					path3.AddCurve(this.lowPoints, pointIndex - 1, 1, base.lineTension);
					path3.Flatten();
				}
				PointF empty = PointF.Empty;
				float[] coord = new float[path3.PointCount * 2];
				PointF[] tfArray4 = path3.PathPoints;
				for (int i = 0; i < path3.PointCount; i++)
				{
					empty = graph.GetRelativePoint(tfArray4[i]);
					coord[2 * i] = empty.X;
					coord[(2 * i) + 1] = empty.Y;
				}
				common.HotRegionsList.AddHotRegion(path3, false, coord, point, series.Name, pointIndex);
			}
			if (brush != null)
			{
				brush.Dispose();
			}
			if (path != null)
			{
				path.Dispose();
				path = null;
			}
		}

		private void FillLastSeriesGradient(ChartGraphics graph)
		{
			if (this.areaPath != null)
			{
				this.areaPath.AddLine(this.areaPath.GetLastPoint().X, this.areaPath.GetLastPoint().Y, this.areaPath.GetLastPoint().X, this.areaBottomPath.GetLastPoint().Y);
			}
			if (this.gradientFill && (this.areaPath != null))
			{
				graph.SetClip(base.Area.PlotAreaPosition.ToRectangleF());
				using (GraphicsPath path = new GraphicsPath())
				{
					path.AddPath(this.areaPath, true);
					this.areaBottomPath.Reverse();
					path.AddPath(this.areaBottomPath, true);
					using (Brush brush = graph.GetGradientBrush(path.GetBounds(), this._series.Color, this._series.BackSecondaryColor, this._series.BackGradientStyle))
					{
						graph.FillPath(brush, path);
						this.gradientFill = false;
					}
				}
				graph.ResetClip();
			}
			if (this.areaPath != null)
			{
				this.areaPath.Dispose();
				this.areaPath = null;
			}
			this.areaBottomPath.Reset();
		}

		protected virtual void GetBottomPointsPosition(CommonElements common, ChartArea area, float axisPosition, ref DataPoint3D firstPoint, ref DataPoint3D secondPoint, out PointF thirdPoint, out PointF fourthPoint)
		{
			Axis axis = area.GetAxis(AxisName.Y, firstPoint.dataPoint.series.YAxisType, firstPoint.dataPoint.series.YSubAxisName);
			float position = (float)axis.GetPosition(firstPoint.dataPoint.YValues[1]);
			thirdPoint = new PointF((float)firstPoint.xPosition, position);
			position = (float)axis.GetPosition(secondPoint.dataPoint.YValues[1]);
			fourthPoint = new PointF((float)secondPoint.xPosition, position);
			if (!float.IsNaN(this._thirdPointY2Value))
			{
				thirdPoint.Y = this._thirdPointY2Value;
			}
			if (!float.IsNaN(this._fourthPointY2Value))
			{
				fourthPoint.Y = this._fourthPointY2Value;
			}
		}

		protected override float GetDefaultTension()
		{
			return 0f;
		}

		public override Image GetImage(ChartTypeRegistry registry)
		{
			return (Image)registry.ResourceManager.GetObject(this.Name + "ChartType");
		}

		public override LegendImageStyle GetLegendImageStyle(Series series)
		{
			return LegendImageStyle.Rectangle;
		}

		protected virtual void GetTopSurfaceVisibility(ChartArea area, DataPoint3D firstPoint, DataPoint3D secondPoint, bool upSideDown, float positionZ, float depth, Matrix3D matrix, ref SurfaceNames visibleSurfaces)
		{
			PointF tf;
			PointF tf2;
			if ((visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top)
			{
				visibleSurfaces ^= SurfaceNames.Top;
			}
			Point3D[] points = new Point3D[3];
			if (!area.ReverseSeriesOrder)
			{
				if ((!upSideDown && (firstPoint.xPosition < secondPoint.xPosition)) || (upSideDown && (firstPoint.xPosition > secondPoint.xPosition)))
				{
					points[0] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth);
					points[1] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
					points[2] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
				}
				else
				{
					points[0] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth);
					points[1] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
					points[2] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
				}
			}
			else if ((!upSideDown && (secondPoint.xPosition < firstPoint.xPosition)) || (upSideDown && (secondPoint.xPosition > firstPoint.xPosition)))
			{
				points[0] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth);
				points[1] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
				points[2] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
			}
			else
			{
				points[0] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth);
				points[1] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
				points[2] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
			}
			matrix.TransformPoints(points);
			if (ChartGraphics.IsSurfaceVisible(points[0], points[1], points[2]))
			{
				visibleSurfaces |= SurfaceNames.Top;
			}
			this.GetBottomPointsPosition(area.Common, area, 0f, ref firstPoint, ref secondPoint, out tf, out tf2);
			if ((visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom)
			{
				visibleSurfaces ^= SurfaceNames.Bottom;
			}
			points = new Point3D[3];
			if (!area.ReverseSeriesOrder)
			{
				if ((!upSideDown && (firstPoint.xPosition < secondPoint.xPosition)) || (upSideDown && (firstPoint.xPosition > secondPoint.xPosition)))
				{
					points[0] = new Point3D((float)firstPoint.xPosition, tf.Y, positionZ + depth);
					points[1] = new Point3D((float)firstPoint.xPosition, tf.Y, positionZ);
					points[2] = new Point3D((float)secondPoint.xPosition, tf2.Y, positionZ);
				}
				else
				{
					points[0] = new Point3D((float)secondPoint.xPosition, tf2.Y, positionZ + depth);
					points[1] = new Point3D((float)secondPoint.xPosition, tf2.Y, positionZ);
					points[2] = new Point3D((float)firstPoint.xPosition, tf.Y, positionZ);
				}
			}
			else if ((!upSideDown && (secondPoint.xPosition < firstPoint.xPosition)) || (upSideDown && (secondPoint.xPosition > firstPoint.xPosition)))
			{
				points[0] = new Point3D((float)secondPoint.xPosition, tf2.Y, positionZ + depth);
				points[1] = new Point3D((float)secondPoint.xPosition, tf2.Y, positionZ);
				points[2] = new Point3D((float)firstPoint.xPosition, tf.Y, positionZ);
			}
			else
			{
				points[0] = new Point3D((float)firstPoint.xPosition, tf.Y, positionZ + depth);
				points[1] = new Point3D((float)firstPoint.xPosition, tf.Y, positionZ);
				points[2] = new Point3D((float)secondPoint.xPosition, tf2.Y, positionZ);
			}
			matrix.TransformPoints(points);
			if (ChartGraphics.IsSurfaceVisible(points[2], points[1], points[0]))
			{
				visibleSurfaces |= SurfaceNames.Bottom;
			}
		}

		protected override bool IsLineTensionSupported()
		{
			return false;
		}

		protected override void ProcessChartType(bool selection, ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			this.gradientFill = false;
			this.lowPoints = null;
			this.indexedBasedX = ChartHelper.IndexedSeries(common, area.GetSeriesFromChartType(this.Name).ToArray());
			base.ProcessChartType(selection, graph, common, area, seriesToDraw);
			this.FillLastSeriesGradient(graph);
		}

		public override bool ExtraYValuesConnectedToYAxis
		{
			get
			{
				return true;
			}
		}

		public override string Name
		{
			get
			{
				return "Range";
			}
		}

		public override int YValuesPerPoint
		{
			get
			{
				return 2;
			}
		}
	}
}

